#include "like.h"

// 辅助函数：比较两个字符，考虑大小写敏感性
inline bool charEquals(char a, char b, bool case_insensitive)
{
    if (case_insensitive)
    {
        return std::tolower(a) == std::tolower(b);
    }
    return a == b;
}

// 递归匹配函数
bool matchPattern(const char *target, const char *pattern,
                  char escape_char, bool case_insensitive)
{
    // 模式结束
    if (*pattern == '\0')
    {
        // 目标也必须结束才匹配
        return *target == '\0';
    }

    // 处理转义字符
    if (*pattern == escape_char)
    {
        // 转义字符后必须跟一个字符
        if (*(pattern + 1) == '\0')
        {
            // 转义字符在模式末尾，视为普通字符
            return *target != '\0' && charEquals(*target, *pattern, case_insensitive) &&
                   matchPattern(target + 1, pattern + 1, escape_char, case_insensitive);
        }

        // 转义后的字符作为普通字符处理
        if (*target == '\0')
        {
            return false; // 目标已结束，无法匹配
        }

        if (charEquals(*target, *(pattern + 1), case_insensitive))
        {
            return matchPattern(target + 1, pattern + 2, escape_char, case_insensitive);
        }
        return false;
    }

    // 处理%通配符
    if (*pattern == '%')
    {
        // 跳过连续的%，因为多个%与一个%效果相同
        while (*(pattern + 1) == '%')
        {
            pattern++;
        }

        // %可以匹配0个或多个字符，尝试所有可能
        // 先尝试匹配0个字符
        if (matchPattern(target, pattern + 1, escape_char, case_insensitive))
        {
            return true;
        }

        // 再尝试匹配1个或多个字符
        if (*target != '\0')
        {
            return matchPattern(target + 1, pattern, escape_char, case_insensitive);
        }

        return false;
    }

    // 处理_通配符
    if (*pattern == '_')
    {
        // _必须匹配恰好1个字符
        if (*target == '\0')
        {
            return false;
        }
        return matchPattern(target + 1, pattern + 1, escape_char, case_insensitive);
    }

    // 普通字符匹配
    if (*target == '\0')
    {
        return false; // 目标已结束，无法匹配
    }

    if (charEquals(*target, *pattern, case_insensitive))
    {
        return matchPattern(target + 1, pattern + 1, escape_char, case_insensitive);
    }

    return false;
}

bool isMysqlLike(const char *target, const std::string &pattern,
                 char escape_char, bool case_insensitive)
{
    // 处理目标为NULL的情况（MySQL中NULL LIKE任何模式均不成立）
    if (target == nullptr)
    {
        return false;
    }

    return matchPattern(target, pattern.c_str(), escape_char, case_insensitive);
}

bool isMysqlLike(std::string target, std::string pattern)
{
    return isMysqlLike(target.c_str(), pattern);
}
